#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <iostream>
#include "Socket.h"

using namespace std;

Socket::Socket(int port) {
	struct sockaddr_in serv_addr;

	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		cout << "exit sockfd" << endl;
		exit(1);
	}

	memset((char *) &serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(port);
	serv_addr.sin_addr.s_addr = INADDR_ANY;

	if (bind(sockfd, (struct sockaddr *) &serv_addr,
			(socklen_t) sizeof(struct sockaddr)) < 0) {
		cout << "no bindea sockfd" << endl;
		cout << "error: " << WSAGetLastError()  << endl;
		exit(1);
	}
	cout << "escucha " << endl;
	listen(sockfd, 10);

   bool TCP_NoDelay = true;
   int OpLen = sizeof(bool);

   int iResult = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &TCP_NoDelay, OpLen);
   if (iResult == SOCKET_ERROR) {
	   cout << "No se pudo setear la opcion TCP_NODELAY en el socket, error: " << WSAGetLastError() << endl;
	} else
		cout << "Seteo correcto de la opcion TCP_NODELAY " << endl;
}



Socket::~Socket() {
	std::cout<<"closesocket"<<std::endl;
	//closesocket(sockfd);
}



void Socket::shutdownSocket() {
	shutdown(sockfd, SD_BOTH);
	closesocket(sockfd);
}



unsigned int Socket::acceptConnection() {
	struct sockaddr_in cli_addr;
	int clilen = (socklen_t) sizeof(cli_addr);
	return accept(sockfd, (struct sockaddr*) &cli_addr, &clilen);
}


int Socket::connectSocket(const char *ip, int port) {
	std::cout<<"connectSocket ip: "<< ip <<" puerto: " << port<<std::endl;
	struct hostent *he;
	struct sockaddr_in their_addr;
	he = gethostbyname(ip);
	std::cout<<"prepre sockfd" << sockfd<<std::endl;
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	their_addr.sin_family = AF_INET;
	their_addr.sin_port = htons(port);
	their_addr.sin_addr = *((struct in_addr *) he->h_addr);
	memset(&(their_addr.sin_zero), 8, sizeof(int));

	//return connect(sockfd, (struct sockaddr *) &their_addr, sizeof(struct sockaddr));
	int resConect = connect(sockfd, (struct sockaddr *) &their_addr, sizeof(struct sockaddr));

    bool TCP_NoDelay = true;
    int OpLen = sizeof(bool);

    int iResult = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &TCP_NoDelay, OpLen);
    if (iResult == SOCKET_ERROR) {
       cout << "No se pudo setear la opcion TCP_NODELAY en el socket, error: " << WSAGetLastError() << endl;
    } else
    	cout << "Seteo correcto de la opcion TCP_NODELAY " << endl;

	return resConect;
}



